<template>
  <div class="draggable-editable-table">
    <div class="card-header" v-if="showClear||showAddRow||selectable||title">
      <div class="card-title">
        <slot name="title">
          <span>{{ title }}</span>
        </slot>
      </div>
      <div class="card-actions">
        <a-button type="primary" v-if="showAddRow" @click="addNewRow">
          <template #icon><PlusOutlined /></template>新增
        </a-button>
        <a-button danger v-if="showClear" @click="clearAll">
          <template #icon><DeleteOutlined /></template>清空
        </a-button>
        <a-button danger v-if="selectable && table.selectedRowKeys.length > 0" @click="clearSelected">
          <template #icon><DeleteOutlined /></template>删除
        </a-button>
      </div>
    </div>

    <div class="table-container">
      <a-table
          id="draggable-table"
          :data-source="dataSource"
          :columns="processedColumns"
          :pagination="false"
          row-key="id"
          :rowSelection="rowSelection()"
          :scroll="scroll"
          bordered
          size="small"
      >
        <template #bodyCell="{ column, record, index }">
          <!-- 拖拽手柄列 -->
          <template v-if="column.key === 'dragHandle'">
            <div class="draggable-handle">
              <MenuOutlined />
            </div>
          </template>
          <!-- 操作列 -->
          <template v-else-if="column.key === 'actions'">
            <div class="row-actions">
              <a-tooltip title="保存">
                <a-button type="link" size="small" @click="saveRow(record)">
                  <template #icon><SaveOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-tooltip title="取消">
                <a-button type="link" size="small" @click="cancelEdit(record)">
                  <template #icon><CloseOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-tooltip title="删除">
                <a-button type="link" size="small" danger @click="deleteRow(index)">
                  <template #icon><DeleteOutlined /></template>
                </a-button>
              </a-tooltip>
            </div>
          </template>
          <!-- 可编辑单元格 -->
          <template v-else>
            <template v-if="record && record.editing && !column.readonly" @click="toggleEditing(record, column.dataIndex)">
              <a-tooltip
                  placement="top"
                  :title="(tooltips[`${column.dataIndex}-${record.id}`] || {}).title"
                  :visible="tooltips[`${column.dataIndex}-${record.id}`]?.visible"
                  :autoAdjustOverflow="true">
                <!-- 文本输入框 -->
                <template v-if="column.type === FormTypes.text || column.type === FormTypes.input">
                  <a-input
                      :id="`${column.dataIndex}-${record.id}`"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      @blur="(e)=>{handleValidate(e.target,index,record,column,'blur')}"
                      @pressEnter="(e)=>{handleValidate(e.target,index,record,column,'key')}"
                  />
                </template>
                <!-- 数字输入框 -->
                <template v-else-if="column.type === 'number' || column.type === FormTypes.inputNumber">
                  <a-input-number
                      :id="`${column.dataIndex}-${record.id}`"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :min="column.min || 0"
                      :max="column.max || 100000"
                      :step="column.step || 1"
                      @blur="(e)=>{handleValidate(e.target,index,record,column,'blur')}"
                      @pressEnter="(e)=>{handleValidate(e.target,index,record,column,'key')}"
                  />
                </template>
                <!-- 复选框 -->
                <template v-else-if="column.type === FormTypes.checkbox">
                  <a-checkbox
                      v-model:checked="record[column.dataIndex]"
                      class="editable-cell-checkbox"
                      :disabled="column.disabled"
                  >
                    {{ column.label || '' }}
                  </a-checkbox>
                </template>
                <!-- 单选框组 -->
                <template v-else-if="column.type === FormTypes.radio">
                  <a-radio-group
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-radio"
                      :disabled="column.disabled"
                  >
                    <a-radio
                        v-for="option in column.options"
                        :key="option.value"
                        :value="option.value"
                    >
                      {{ option.label }}
                    </a-radio>
                  </a-radio-group>
                </template>
                <!-- 下拉选择器 -->
                <template v-else-if="column.type === FormTypes.select">
                  <a-select
                      :id="`${column.dataIndex}-${record.id}`"
                      @change="(v)=>{handleValidate(v,index,record,column,'change')}"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :options="column.options"
                      :disabled="column.disabled"
                      :placeholder="column.placeholder || '请选择'"
                  />
                </template>
                <!-- 带搜索的下拉选择器 -->
                <template v-else-if="column.type === FormTypes.sel_search">
                  <a-select
                      :id="`${column.dataIndex}-${record.id}`"
                      @change="(v)=>{handleValidate(v,index,record,column,'change')}"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :options="column.options"
                      :disabled="column.disabled"
                      show-search
                      :placeholder="column.placeholder || '搜索选择'"
                      :filter-option="(input, option) => {
                        return option?.label?.toLowerCase().includes(input.toLowerCase())
                      }"
                  />
                </template>
                <!-- 多选列表 -->
                <template v-else-if="column.type === FormTypes.list_multi">
                  <a-select
                      :id="`${column.dataIndex}-${record.id}`"
                      @change="(v)=>{handleValidate(v,index,record,column,'change')}"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :options="column.options"
                      :disabled="column.disabled"
                      mode="multiple"
                      :placeholder="column.placeholder || '请选择多项'"
                  />
                </template>
                <!-- 日期选择器 -->
                <template v-else-if="column.type === FormTypes.date">
                  <a-date-picker
                      :id="`${column.dataIndex}-${record.id}`"
                      @change="(v)=>{handleValidate(v,index,record,column,'change')}"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :format="column.format || 'YYYY-MM-DD'"
                      :value-format="column.format || 'YYYY-MM-DD'"
                      :disabled="column.disabled"
                  />
                </template>
                <!-- 日期时间选择器 -->
                <template v-else-if="column.type === FormTypes.datetime">
                  <a-date-picker
                      :id="`${column.dataIndex}-${record.id}`"
                      @change="(v)=>{handleValidate(v,index,record,column,'change')}"
                      v-model:value="record[column.dataIndex]"
                      class="editable-cell-input"
                      :format="column.format || 'YYYY-MM-DD HH:mm:ss'"
                      :value-format="column.format || 'YYYY-MM-DD HH:mm:ss'"
                      :disabled="column.disabled"
                      show-time
                      :show-time-format="column.timeFormat || 'HH:mm:ss'"
                  />
                </template>
                <!-- 图片上传 -->
                <template v-else-if="column.type === FormTypes.image">
                  <a-upload
                      v-model:file-list="record[column.dataIndex]"
                      :action="column.uploadUrl"
                      list-type="picture-card"
                      :max-count="column.maxCount || 1"
                      :before-upload="column.beforeUpload"
                      @change="handleUploadChange(record, column.dataIndex, $event)"
                  >
                    <div v-if="(record[column.dataIndex] || []).length < (column.maxCount || 1)">
                      <PlusOutlined />
                      <div style="margin-top: 8px">上传</div>
                    </div>
                  </a-upload>
                </template>
                <!-- 文件上传 -->
                <template v-else-if="column.type === FormTypes.file || column.type === FormTypes.upload">
                  <a-upload
                      v-model:file-list="record[column.dataIndex]"
                      :action="column.uploadUrl"
                      :max-count="column.maxCount || 1"
                      :before-upload="column.beforeUpload"
                      @change="handleUploadChange(record, column.dataIndex, $event)">
                    <a-button>
                      <UploadOutlined /> 选择文件
                    </a-button>
                  </a-upload>
                </template>
                <!-- 弹出层编辑 -->
                <template v-else-if="column.type === FormTypes.popup">
                  <a-popover
                      trigger="click"
                      :title="column.popupTitle || '编辑内容'"
                      @visibleChange="(visible) => { if (!visible) saveRow(record); }"
                  >
                    <template #content>
                      <component
                          :is="column.popupComponent"
                          v-model:value="record[column.dataIndex]"
                          :record="record"
                          :column="column"
                      />
                      <div style="margin-top: 10px; text-align: right">
                        <a-button size="small" @click="saveRow(record)">确认</a-button>
                      </div>
                    </template>
                    <div class="editable-cell">
                      {{ formatValue(record[column.dataIndex], column) || '点击编辑' }}
                    </div>
                  </a-popover>
                </template>
                <!-- 普通文本（非编辑状态） -->
                <template v-else-if="column.type === FormTypes.normal">
                  <div class="editable-cell-static" >
                  </div>
                </template>
                <!-- 自定义编辑组件 -->
                <template v-else-if="column.customEdit">
                  <component
                      :is="column.customEdit"
                      v-model:value="record[column.dataIndex]"
                      :record="record"
                      :column="column"
                  />
                </template>
              </a-tooltip>
            </template>
            <template v-else>
<!--              class="editable-cell" 这个样式会干扰align-->
              <div v-if="record" @click="toggleEditing(record, column.dataIndex)">
                <!-- 处理 rowIndex 列 -->
                <template v-if="column.key === 'rowIndex'">
                   {{ record.id + 1 }}
                </template>
                <!-- 格式化显示内容 -->
                <template v-else-if="column.type === FormTypes.date && record[column.dataIndex]">
                  {{ formatDate(record[column.dataIndex], column.format || 'YYYY-MM-DD') }}
                </template>
                <template v-else-if="column.type === FormTypes.datetime && record[column.dataIndex]">
                  {{ formatDate(record[column.dataIndex], column.format || 'YYYY-MM-DD HH:mm:ss') }}
                </template>
                <template v-else-if="column.type === FormTypes.select || column.type === FormTypes.sel_search">
                  {{ getOptionLabel(column, record[column.dataIndex]) }}
                </template>
                <template v-else-if="column.type === FormTypes.list_multi">
                  {{ getMultiOptionLabels(column, record[column.dataIndex]) }}
                </template>
                <template v-else-if="column.type === FormTypes.checkbox">
                  <CheckOutlined v-if="record[column.dataIndex]" />
                  <CloseOutlined v-else />
                </template>
                <template v-else-if="column.type === FormTypes.image && record[column.dataIndex] && record[column.dataIndex].length">
                  <a-avatar :src="record[column.dataIndex][0].url || record[column.dataIndex][0].thumbUrl" size="small" />
                  <span v-if="record[column.dataIndex].length > 1">
                    +{{ record[column.dataIndex].length - 1 }}
                  </span>
                </template>
                <template v-else-if="(column.type === FormTypes.file || column.type === FormTypes.upload) && record[column.dataIndex] && record[column.dataIndex].length">
                  <FileOutlined />
                  <span class="file-name">{{ record[column.dataIndex][0].name }}</span>
                  <span v-if="record[column.dataIndex].length > 1">
                    +{{ record[column.dataIndex].length - 1 }}
                  </span>
                </template>
                <template v-else-if="column.customDisplay">
                  <component
                      :is="column.customDisplay"
                      :value="record[column.dataIndex]"
                      :record="record"
                      :column="column"
                  />
                </template>
                <template v-else>
                  {{ record[column.dataIndex] !== undefined ? record[column.dataIndex] : '' }}
                </template>
              </div>
            </template>
          </template>
        </template>
      </a-table>

      <!-- 空状态 -->
<!--      <a-empty v-if="dataSource.length === 0" class="empty-state">-->
<!--        <template #image>-->
<!--          <InboxOutlined style="font-size: 48px; color: #d9d9d9;" />-->
<!--        </template>-->
<!--        <template #description>-->
<!--          <span>暂无数据</span>-->
<!--        </template>-->
<!--        <a-button type="primary" @click="addNewRow">添加新行</a-button>-->
<!--      </a-empty>-->
    </div>

    <div class="footer-stats" v-if="showStats">
      <div>总记录数: <span class="highlight">{{ dataSource.length }}</span> 条</div>
      <div>最后编辑: <span class="highlight">{{ lastEdited || '--' }}</span></div>
    </div>
    <div class="card-footer" v-if="showFooter">
        <slot name="footer">
        </slot>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue';
import { FormTypes } from '@/utils/JEditableTableUtil.js'
import {
  PlusOutlined,
  DeleteOutlined,
  SaveOutlined,
  CloseOutlined,
  MenuOutlined,
  CheckOutlined,
  FileOutlined,
  UploadOutlined
} from '@ant-design/icons-vue';
import Sortable from 'sortablejs';
import _ from 'lodash'
import { message } from "ant-design-vue";


const props = defineProps({
  // 表格标题
  title: {
    type: String, default: ''
  },
  // 表格列配置
  columns: {
    type: Array, required: true
  },
  // 初始数据
  initialData: {
    type: Array, default: () => []
  },
  scroll: {
    type: Object
  },
  // 是否显示清空按钮
  dataIdAttr: {
    type: String, default: 'id'
  },
  // 是否显示清空按钮
  showClear: {
    type: Boolean, default: false
  },
  // 是否显示拖拽手柄
  showDragHandle: {
    type: Boolean, default: true
  },
  // 是否显示操作列
  showActions: {
    type: Boolean, default: false
  },
  showStats: {
    type: Boolean, default: false
  },
  showFooter: {
    type: Boolean, default: false
  },
  // 是否可以选择删除行
  deletable: {
    type: Boolean, default: false
  },
  // 是否显示添加行按钮
  showAddRow: {
    type: Boolean, default: false
  },
  // 是否显示序号列
  showSequence: {
    type: Boolean, default: true
  },
});

const emit = defineEmits([
  'update:data',
  'row-added',
  'row-deleted',
  'row-saved',
  'data-cleared',
  'upload-success'
]);
// 处理后的列配置
const processedColumns = computed(() => {
  const columns = [...props.columns];
  // 添加序号
  if (props.showSequence) {
    columns.unshift(   {
      title: '#', key: 'rowIndex', width: 30, align: 'center', readonly: true,
      customRender: function({text, record, index}) {
        return (parseInt(index) + 1).toString()
      }
    });
  }
  // 添加拖拽手柄列
  if (props.showDragHandle) {
      columns.unshift({
        title: '',
        key: 'dragHandle',
        width: 50,
        align: 'center',
        readonly: true
      });
  }

  // 添加操作列
  if (props.showActions) {
      columns.push({
        title: '操作',
        key: 'actions',
        width: 120,
        align: 'center',
        readonly: true
      });
  }
  return columns;
});
const selectable = computed(() => {
  return props.deletable
})
// 表格数据
const tooltips = ref({});
const noPassedIds = ref([])
props.initialData.forEach((record, index)=>{
  //数据库记录
  record.visible = record.visible === undefined? true: !!record.visible
  record.sorter =  Boolean(record.sorter)
  if(!record.id) record.id = index;
})
// console.error("initialData", JSON.stringify(props.initialData))
// const dataSource = ref([...props.initialData]);
// 最后编辑时间
const lastEdited = ref(null);
const table = reactive({
  selectedRowKeys: []
})
const dataSource = ref([])
const dataBak = ref([])
dataBak.value = _.cloneDeep(props.initialData);
watchEffect(()=>{
  dataSource.value = props.initialData
})

/* methods */
/** 验证单个表单 */
const validateOneInput = (value, record, column, notPassedIds, update = false, validType = 'input') => {
  let tooltip_objs = Object.assign({}, tooltips.value)
  // let notPassedIds = cloneObject(this.notPassedIds)
  let inputId = `${column.dataIndex}-${record.id}`
  tooltip_objs[inputId] = tooltip_objs[inputId] ? tooltip_objs[inputId] : {}
  let [passed, message] = validateValue(column, value, validType)
  const nextThen = res => {
      let [passed, message] = res
      if (passed == null) {
        // debugger
      }
      if (passed == null && tooltip_objs[inputId].visible != null) {
        return
      }
      passed = passed == null ? true : passed
      tooltip_objs[inputId].visible = !passed
      tooltip_objs[inputId].passed = passed
      let index = notPassedIds.indexOf(inputId)
      let borderColor = null, boxShadow = null
      if (!passed) {
        tooltip_objs[inputId].title = replaceProps(column, message)
        borderColor = 'red'
        boxShadow = `0 0 0 2px rgba(255, 0, 0, 0.2)`
        if (index === -1) notPassedIds.push(inputId)
      } else {
        if (index !== -1) notPassedIds.splice(index, 1)
      }

      let element = document.getElementById(inputId)
      // console.error("initial element:",element)
      if (element != null) {
        // select 在 .ant-select-selection 上设置 border-color
        if (column.type === FormTypes.select||column.type === FormTypes.sel_search
            || column.type === FormTypes.date || column.type === FormTypes.datetime) {
          // element = element.getElementsByClassName('ant-select')[0]
          element = element.parentNode.parentNode
        }
        if (column.type === FormTypes.list_multi) {
          element = element.parentNode.parentNode.parentNode.parentNode
        }
        // if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
        //   element = element.getElementsByTagName('input')[0]
        // }
        element.style.borderColor = borderColor
        element.style.boxShadow = boxShadow
        if (element.tagName === 'SPAN') {
          element.style.display = 'block'
        }
      }
      // 是否更新到data
      if (update) {
        tooltips.value = tooltip_objs
        noPassedIds.value = notPassedIds
      }
  }

  if (typeof passed === 'function') {
    let executed = false
    passed(validType, value, row, column, (flag, msg) => {
      if (executed) return
      executed = true
      if (typeof msg === 'string') {
        message = msg
      }
      if (flag == null || flag === true) {
        nextThen([true, message])
      } else {
        nextThen([false, message])
      }
    })
  } else {
    nextThen([passed, message])
  }

  return [tooltips[inputId], notPassedIds]
}
/** 通过规则验证值是否正确 */
const validateValue = (column, value, validType = 'blur') => {
  console.error("validate value:", value)
  let rules = column.validateRules
  let passed = true, message = ''
  // 判断有没有验证规则或验证规则格式正不正确，若条件不符合则默认通过
  if (rules instanceof Array) {
    for (let rule of rules) {
      // 当前值是否为空
      let isNull = (value == null || value === '')
      // 验证规则：非空
      if (rule.required === true && isNull) {
        passed = false
      } else // 使用 else-if 是为了防止一个 rule 中出现两个规则
          // 验证规则：正则表达式
      if (!!rule.pattern && !isNull) {
        // 兼容 online 的规则
        let foo = [
          { title: '6到16位数字', value: 'n6-16', pattern: /\d{6,16}/ },
          { title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/ },
          { title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/ },
          { title: '电子邮件', value: 'email', pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/ },
          { title: '手机号码', value: 'phone', pattern: /^1[3456789]\d{9}$/ },
          { title: '邮政编码', value: 'postcode', pattern: /^[1-9]\d{5}$/ },
          { title: '中文', value: 'zh', pattern: /^[\u4e00-\u9fa5]+$/ },
          { title: 'IP', value: 'ip', pattern: /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/ },
          { title: '数字和字母', value: 'n-s', pattern: /^[A-Za-z0-9]+$/ },
          { title: '数字和字母下划线', value: 'n-s-', pattern: /^[A-Za-z0-9_]+$/ },
          { title: '时间', value: 'time', pattern: /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/ },
          { title: '日期时间', value: 'datetime', pattern: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/ },
          { title: '日期', value: 'date', pattern: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/ },
          { title: '整数和百分比', value: 'n,%', pattern: /^[1-9]?[0-9]*%?$/ },
          { title: '字母', value: 's', pattern: /^[A-Z|a-z]+$/ },
          { title: '数字', value: 'n', pattern: /^-?\d+\.?\d*$/ },
          { title: '整数', value: 'z', pattern: /^-?\d+$/ },
          { title: '非空', value: '*', pattern: /^.+$/ },
          { title: '6到18位字符串', value: 's6-18', pattern: /^.{6,18}$/ },
          { title: '金额', value: 'money', pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/ },
        ]
        let flag = false
        for (let item of foo) {
          if (rule.pattern === item.value && item.pattern) {
              passed = new RegExp(item.pattern).test(value)
              console.error("passed?",passed)
              flag = true
              break
          }
        }
        // 其它验证
        if (!flag){
          if (rule.pattern === "uniq"){
              let stats = {}
              stats[value] = 0
              dataSource.value.forEach((item)=>{
                  if(item.dataIndex === value) stats[value]++
              })
              passed = stats[value] < 2
          }else
            passed = new RegExp(rule.pattern).test(value)
        }
      } else
          // 校验规则：自定义函数校验
      if (typeof rule.validator === 'function') {
        return [rule.validator(value), rule.message]
      }
      // 如果没有通过验证，则跳出循环。如果通过了验证，则继续验证下一条规则
      if (!passed) {
        message = rule.message
        break
      }
    }
  }
  if(!message) message = `${column.title}输入不合法`
  return [passed, message]
}

const validateEditingItem = () =>{
    dataSource.value.forEach((record)=>{
      if(record.editing){
        //console.error("record:", record)
        props.columns.forEach((column)=>{
          if(column.validateRules){
              validateOneInput(record[column.dataIndex], record, column, noPassedIds.value, true, '')
          }
        })
      }
    })
}

const handleValidate = (target, index, record, column, event) => {
   let value
   if(event === 'blur')
     value = target.value
   else if (event === 'change')
     value = target
   else
     value = target && target.value
  // 做单个表单验证
  validateOneInput(value, record, column, noPassedIds.value, true, 'blur')
}

// 添加新行
const addNewRow = () => {
  let newKey
  if (props.dataIdAttr !== 'id'){ //id与主键可以分离开来
     newKey = "new" + dataSource.value.length;
  } else {
     newKey = dataSource.value.length;
  }
  const newRow = {editing: true, id: dataSource.value.length};
  newRow[props.dataIdAttr] = newKey
  // 初始化各列默认值
  props.columns.forEach(col => {
    if (col.defaultValue !== undefined) {
      newRow[col.dataIndex] = col.defaultValue;
    } else if ([FormTypes.inputNumber].includes(col.type)) {
      newRow[col.dataIndex] = 0;
    } else if ([FormTypes.checkbox].includes(col.type)) {
      newRow[col.dataIndex] = false;
    } else if ([FormTypes.list_multi].includes(col.type)) {
      newRow[col.dataIndex] = [];
    } else if ([FormTypes.image, FormTypes.file, FormTypes.upload].includes(col.type)) {
      newRow[col.dataIndex] = [];
    } else {
      newRow[col.dataIndex] = '';
    }
  });
  console.error("newRow:", JSON.stringify(newRow))
  dataSource.value.forEach((record)=>{
    record.editing = false
  })
  dataSource.value.push(newRow);
  lastEdited.value = new Date().toLocaleString();
  emit('row-added', newRow);
};

// 删除行
const deleteRow = (index) => {
  console.error("删除行:", index+1)
  const deletedRow = dataSource.value.splice(index, 1)[0];
  lastEdited.value = new Date().toLocaleString();
  emit('row-deleted', deletedRow);
};

// 清空表格
const clearAll = () => {
  dataSource.value = [];
  lastEdited.value = new Date().toLocaleString();
  emit('data-cleared');
};
// 清空指定行
const clearSelected = () => {
  table.selectedRowKeys.forEach(id => {
    　　//删除一次后，数组的原index会改变，所以要重新计算index
       let index = dataSource.value.findIndex((item)=>item.id === id);
       dataSource.value.splice(index, 1);
  });
  // id重构
  dataSource.value.forEach((item, index)=>{
    item.id = index;
  })
  console.error(JSON.stringify(dataSource.value));
  table.selectedRowKeys = [];
};
// 开始编辑
const toggleEditing = (record, field) => {
  console.error("toggleEditing")
  let  passed = true
  const toSave = (row) => {
      for(let i in row){
        let inputId = `${i}-${row.key}`
        if(noPassedIds.value && noPassedIds.value.includes(inputId)){
          row.editing = true
          return false
        }
      }
      row.editing = !row.editing
      return true
  }
  // 如果已有其他行在编辑，先保存
  const editingRows = dataSource.value.filter(row => row.editing);
  editingRows.forEach((editingRow)=> {
    if (editingRow && editingRow !== record)
        passed = toSave(editingRow)
  })
  // 当前记录处理;保存原始值用于取消编辑时恢复
  record._originalValues = { ...record };
  // console.error(JSON.stringify(noPassedIds.value), `${field}-${record.id}`)
  record.editingField = field;
  if(passed) toSave(record)
};

// 保存行
const saveRow = (record) => {
  record.editing = false;
  record.editingField = null;
  delete record._originalValues;
  lastEdited.value = new Date().toLocaleString();
  emit('row-saved', record);
};

// 取消编辑
const cancelEdit = (record) => {
  if (record._originalValues) {
    Object.keys(record._originalValues).forEach(key => {
      record[key] = record._originalValues[key];
    });
  }
  record.editing = false;
  record.editingField = null;
  delete record._originalValues;
};

// 格式化日期
const formatDate = (dateStr, format = 'YYYY-MM-DD') => {
  if (!dateStr) return '';

  try {
    const date = new Date(dateStr);
    if (isNaN(date.getTime())) return dateStr;

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    if (format === 'YYYY-MM-DD HH:mm:ss') {
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    } else if (format === 'YYYY-MM-DD') {
      return `${year}-${month}-${day}`;
    } else if (format === 'YYYY/MM/DD') {
      return `${year}/${month}/${day}`;
    } else if (format === 'MM-DD') {
      return `${month}-${day}`;
    }
    return dateStr;
  } catch (e) {
    return dateStr;
  }
};

// 获取选项标签
const getOptionLabel = (column, value) => {
  if (!column.options || !value) return value;
  const option = column.options.find(opt => opt.value === value);
  //console.error("option:", JSON.stringify(option))
  return option ? option.label : value;
};

// 获取多选项标签
const getMultiOptionLabels = (column, values) => {
  if (!column.options || !values || !values.length) return '';
  return values
      .map(value => {
        const option = column.options.find(opt => opt.value === value);
        return option ? option.label : value;
      })
      .join(', ');
};

// 格式化显示值
const formatValue = (value, column) => {
  if (value === undefined || value === null) return '';
  // 根据不同类型格式化
  switch (column.type) {
    case 'checkbox':
      return value ? '是' : '否';
    case 'list_multi':
      return getMultiOptionLabels(column, value);
    default:
      return value.toString();
  }
};

/** 辅助方法：替换${...}变量 */
const replaceProps = (col, text) => {
  if (text && typeof text === 'string') {
      text = text.replace(/\${title}/g, col.title)
      text = text.replace(/\${key}/g, col.key)
      text = text.replace(/\${defaultValue}/g, col.defaultValue)
  }
  return text
}

// 处理上传变化
const handleUploadChange = (record, field, info) => {
  if (info.file.status === 'done') {
    emit('upload-success', {
      record,
      field,
      file: info.file,
      response: info.file.response
    });
  }
  // 更新记录中的文件列表
  record[field] = info.fileList;
};

// 初始化拖拽功能
const initDragAndDrop = () => {
  const tbody = document.querySelector('#draggable-table .ant-table-tbody');
  if (!tbody) return;
  console.error("props.dataIdAttr:", props.dataIdAttr)
  console.error("datasource:",JSON.stringify(dataSource.value));
  new Sortable(tbody, {
    animation: 150,
    handle: '.draggable-handle',
    dataIdAttr: props.dataIdAttr, // 指定使用index属性作为唯一标识
    ghostClass: 'drag-over',
    onEnd: (evt) => {``
      // // 拖拽结束后重新排序数据,增加了空行，所以去除
      // const { oldIndex, newIndex } = evt;
      // if (oldIndex !== newIndex) {
      //   const data = [...dataSource.value];
      //   const [movedItem] = data.splice(oldIndex, 1);
      //   data.splice(newIndex, 0, movedItem);
      //   dataSource.value = data;
      //   lastEdited.value = new Date().toLocaleString();
      // }
    }
  });
};

const rowSelection = () => {
  if(selectable.value) {
    return {
      selectedRowKeys: table.selectedRowKeys,
      onChange: (selectedRowKeys, selectedRows) => {
        console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
        table.selectedRowKeys = selectedRowKeys
      }
    };
  }
}

const checkIfAllPassed = (errorMsg)=>{
  let passed = true
  Object.values(tooltips.value).forEach((item) => {
      if(item.visible){
         message.error(errorMsg||`验证不通过！`)
         passed = false
         return false;
      }
  })
  return passed
}

const apply = ()=>{
  if (checkIfAllPassed()){ //录入验证
      console.log('apply.....')
      dataSource.value.forEach((record)=>{
          if( /\d+$/.test(record.width)){
            record.width = parseInt(record.width)
          }
          record.editing = false;
          record.editingField = undefined;
      })
      console.error(JSON.stringify(dataSource.value))
      emit('update:data', dataSource.value); //用于即时更新
      return true;
  }
  return false;
}

const rollback = ()=>{
  console.log('rollback');
  dataSource.value = _.clone(dataBak.value);
  emit('update:data', dataSource.value);  //用于即时更新
}

const save = (callback) => {
  if(apply()) callback();
}

const reset =  (callback) => {
  callback()
}

onMounted(() => {
  setTimeout(initDragAndDrop, 500);
});

defineExpose({addNewRow, rollback, checkIfAllPassed, apply, save, reset})
</script>

<style scoped>
.draggable-editable-table {
  width: 100%;
  background: white;
  border-radius: 12px;
  padding: 15px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08);
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #f0f0f0;
}

.card-title {
  font-size: 1.4rem;
  color: #2c3e50;
  display: flex;
  align-items: center;
  gap: 10px;
}

.card-actions {
  display: flex;
  gap: 10px;
}

.table-container {
  overflow-x: auto;
  position: relative;
  min-height: 200px;
}

.draggable-handle {
  cursor: move;
  font-size: 16px;
  color: #999;
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.editable-cell {
  position: relative;
  padding: 5px 12px;
  cursor: pointer;
  min-height: 32px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
}

.editable-cell:hover {
  border: 1px dashed #1890ff;
  border-radius: 4px;
  padding: 4px 11px;
}

.editable-cell-input,
.editable-cell-radio {
  width: 100%;
}

.editable-cell-checkbox {
  margin: 5px 0;
}

.editable-cell-static {
  padding: 5px 0;
}

.row-actions {
  display: flex;
  gap: 4px;
  justify-content: center;
}

.footer-stats {
  margin-top: 20px;
  padding: 15px;
  background: #f9f9f9;
  border-radius: 8px;
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: #666;
}

.highlight {
  font-weight: bold;
  color: #1890ff;
}

.drag-over {
  background-color: #e6f7ff !important;
}

.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #bfbfbf;
}

.file-name {
  margin-left: 4px;
  max-width: 150px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-footer {
  display: flex;
  justify-content: flex-end;  /* Aligns content to the right */
  padding: 10px;
  margin-top: auto;          /* Pushes footer to bottom */
  text-align: right;         /* Right-aligns text content */
}
</style>